namespace Geekeradmin.Middleware
{
    /// <summary>
    /// 图片访问防盗链中间件
    /// </summary>
    public class PhotoatcMiddleWare
    {
        private readonly RequestDelegate _next;

        public PhotoatcMiddleWare(RequestDelegate next)
        {
            _next = next;
        }

        public async Task Invoke(HttpContext context)
        {
            string url = context.Request.Path.Value;
            if (!url.Contains(".jpg") && !url.Contains(".png") && !url.Contains(".bmp") && !url.Contains(".jpeg") && !url.Contains(".gif"))
            {
                if (!context.Response.HasStarted)
                {
                    await _next.Invoke(context);//走正常流程
                }
            }
            else
            {
                string urlReferrer = context.Request.Headers["Referer"];
                if (string.IsNullOrWhiteSpace(urlReferrer))//拒绝直接访问图片
                {
                    await this.SetForbiddenImage(context);//返回404图片
                }
                else if (!urlReferrer.Contains("localhost"))//拒绝非当前域名访问图片
                {
                    await this.SetForbiddenImage(context);//返回404图片
                }
                else
                {
                    if (!context.Response.HasStarted)
                    {
                        await _next.Invoke(context);//走正常流程
                    }
                }
            }
        }
        /// <summary>
        /// 设置拒绝图片
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        private async Task SetForbiddenImage(HttpContext context)
        {
            string defaultImagePath = "wwwroot/Image/Forbidden.jpg";
            string path = Path.Combine(Directory.GetCurrentDirectory(), defaultImagePath);

            FileStream fs = File.OpenRead(path);
            byte[] bytes = new byte[fs.Length];
            await fs.ReadAsync(bytes, 0, bytes.Length);
            if (!context.Response.HasStarted)
            {
                await context.Response.Body.WriteAsync(bytes, 0, bytes.Length);
            }
        }
    }
}
